# -*-coding:utf-8-*-
import find_c_file
import module_anlyzer
import model
import argopt
import win32api
import win32con
import time
import json
import os


def remove_duplicate_unit(input_list):
    if len(input_list) > 0:
        return sorted(set(input_list), key=input_list.index)
    else:
        return input_list


class project_analyzer:
    module_infos = []
    project_function_call_trees = []  # with different task origins
    interface_included_trees = []  # with different task origins
    data_reference_tree = []  # refer
    custom_handlers = []
    jmodule_list = []

    def __init__(self, files):
        for c_file in files:
            fp = open(c_file)
            if fp is None:
                print('c file path error (' + c_file +
                      '),and will be closed in 3 seconds')
                time.sleep(3)
                exit(0)
            lines = []
            for line in fp:
                lines.append(line)
            fp.close()
            anlyzer = module_anlyzer.module_analyzer(c_file, lines)
            module = anlyzer.start()
            self.module_infos.append(module)
            jfunc_list = []
            dec_list_tmp = []
            for func_dec_list in module.func_dec_list:
                dec_list_tmp.append(func_dec_list['dec_name'])
            for func_info in module.function_list:
                if c_file == func_info.defined_path:
                    func_info.called_functions = remove_duplicate_unit(func_info.called_functions)
                    func_call_list = []
                    for called_funciton in func_info.called_functions:
                        if called_funciton in dec_list_tmp:
                             func_call_list.append(called_funciton)
                    jfunc_list.append({
                        "func_name":
                        func_info.name,
                        "func_content":
                        func_info.func_content,
                        "ret_type":
                        func_info.ret_type,
                        "args":
                        func_info.arg_infos,
                        "read_paras":
                        remove_duplicate_unit(func_info.read_paras),
                        "write_paras":
                        remove_duplicate_unit(func_info.write_paras),
                        "called_functions":
                        func_call_list
                    })
            jpara_list = []
            for para_info in module.para_list:
                jpara_list.append({
                    "name" : para_info.name,
                    "type_name" : para_info.type_name
                })

            jenum_list = []
            for enum_info in module.type_info.enum_list:
                jenum_list.append({
                    "enum_name": enum_info.name,
                    "member_list": enum_info.member_list
                })
            jstruct_list = []
            for struct_info in module.type_info.struct_list:
                jstruct_list.append({
                    "struct_name": struct_info.name,
                    "member_list": struct_info.member_list
                })
            junion_list = []
            for union_info in module.type_info.union_list:
                junion_list.append({
                    "union_name": union_info.name,
                    "member_list": union_info.union_list
                })
            self.jmodule_list.append({
                "module_path": module.module_name,
                "func_infos": jfunc_list,
                "func_dec_list": module.func_dec_list,
                "e_datas_in_module": module.e_datas_in_module,
                "para_list": jpara_list,
                "enum_list": jenum_list,
                "struct_list": jstruct_list,
                "union_list": junion_list,
                "typedef_list": module.type_info.type_def_list
            })
            print('Please confirm if the last line in c file of module \n << '+ c_file +' >> \n is analyzed!')
            os.system('pause')


if __name__ == "__main__":
    data = [{
        'name': 'path',
        'type': type(str),
        'default': "..\\ldc70UnittestBench\\workspace\\",
        'comment': 'path'
    }, {
        'name': 'help',
        'type': type(bool),
        'default': False,
        'comment': 'static analyze c project '
    }]

    help_text = '''
     c_project_static_analyzer created by WPz.
       syntax:
             c_project_static_analyzer.py path=
       example:
             c_project_static_analyzer.py path=C:\\sandBox\\workspace\\src\\
     '''

    error, unknown, args, opts = argopt.parse(data, help_text)
    files = find_c_file.DirAll(opts['path'])
    if (files == 'FAIL'):
        win32api.MessageBox(
            0, "exist error!", opts['path'],
            win32con.MB_OK | win32con.MB_TOPMOST | win32con.MB_SYSTEMMODAL)
    else:
        pathtmp = os.getcwd()
        project = project_analyzer(files)
        fp = open(pathtmp + '/output/output.json', mode='w+')
        fp.write(str(json.dumps(project.jmodule_list)))
        fp.close()
        print("analyze finished. analyze tool version : V1.01")
